﻿using SceneEngine;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using SceneEditor.UI;

namespace SceneEditor
{
    public class MoveObjectGroupsAction : EditAction
    {
        private List<string> objectNames;

        private List<string> oldGroupPaths;
        private List<string> newGroupPaths;

        private List<string> undoFoldersToCleanUp;
        private List<string> redoFoldersToCleanUp;

        private MultiSelectTreeview objectTree;

        public MoveObjectGroupsAction(List<string> objectNames, List<string> oldGroupPaths, 
            List<string> newGroupPaths, List<string> foldersToCleanUp, MultiSelectTreeview objectTree)
        {
            this.objectNames = objectNames;

            this.oldGroupPaths = oldGroupPaths;
            this.newGroupPaths = newGroupPaths;

            this.undoFoldersToCleanUp = foldersToCleanUp;
            redoFoldersToCleanUp = new List<string>();

            this.objectTree = objectTree;
        }

        private void MoveTreeNodes(string oldPath, string newPath, BaseObject baseObject, bool undo)
        {
            string[] nodeIndices = oldPath.Split('|');

            TreeNodeCollection insertCollection = objectTree.Nodes;
            TreeNode parentNode = insertCollection[0];

            bool first = true;

            for (int i = 0; i < nodeIndices.Length; i++)
            {
                if (insertCollection.ContainsKey(nodeIndices[i]) == false)
                {
                    insertCollection.Add(nodeIndices[i], nodeIndices[i], 0);

                    if (first)
                    {
                        first = false;

                        if (undo == true)
                        {
                            redoFoldersToCleanUp.Add(objectTree.GetGroupPathFromNode(insertCollection[nodeIndices[i]], true));
                        }
                    }
                }

                parentNode = insertCollection[nodeIndices[i]];
                insertCollection = insertCollection[nodeIndices[i]].Nodes;
            }

            if (insertCollection != null)
            {
                TreeNode originalNode = objectTree.GetNodeFromGroupPath(
                    newPath, baseObject.Name);

                TreeNode newNode = (TreeNode)originalNode.Clone();
                insertCollection.Insert(0, newNode);

                originalNode.Remove();
            }
        }
        
        public override void Undo()
        {
            objectTree.BeginUpdate();
            redoFoldersToCleanUp.Clear();

            for (int n = 0; n < objectNames.Count; n++)
            {
                BaseObject baseObject = EngineGlobals.Scene.GetBaseObject(objectNames[n]);
                baseObject.GroupPath = oldGroupPaths[n];

                MoveTreeNodes(oldGroupPaths[n], newGroupPaths[n], baseObject, true);
            }

            for (int i = 0; i < undoFoldersToCleanUp.Count; i++)
            {
                TreeNode node = objectTree.GetNodeFromGroupPath(undoFoldersToCleanUp[i]);
                node.Remove();
            }

            objectTree.Sort();
            objectTree.EndUpdate();
        }
        public override void Redo()
        {
            objectTree.BeginUpdate();

            for (int n = 0; n < objectNames.Count; n++)
            {
                BaseObject baseObject = EngineGlobals.Scene.GetBaseObject(objectNames[n]);
                baseObject.GroupPath = newGroupPaths[n];

                MoveTreeNodes(newGroupPaths[n], oldGroupPaths[n], baseObject, false);
            }

            for (int i = 0; i < redoFoldersToCleanUp.Count; i++)
            {
                TreeNode node = objectTree.GetNodeFromGroupPath(redoFoldersToCleanUp[i]);
                node.Remove();
            }

            objectTree.Sort();
            objectTree.EndUpdate();
        }
    }
}
